use crate::{Address, Byte, Result};

/// RAM 模块
pub struct Ram {
    data: Vec<Byte>,
}

impl Ram {
    pub fn new(size: usize) -> Self {
        Ram {
            data: vec![0; size],
        }
    }

    pub fn read(&self, address: Address) -> Result<Byte> {
        let addr = address as usize;
        if addr < self.data.len() {
            Ok(self.data[addr])
        } else {
            Err(crate::EmulatorError::InvalidMemoryAccess(address))
        }
    }

    pub fn write(&mut self, address: Address, value: Byte) -> Result<()> {
        let addr = address as usize;
        if addr < self.data.len() {
            self.data[addr] = value;
            Ok(())
        } else {
            Err(crate::EmulatorError::InvalidMemoryAccess(address))
        }
    }

    pub fn load(&mut self, start_address: Address, data: &[Byte]) -> Result<()> {
        let start = start_address as usize;
        if start + data.len() <= self.data.len() {
            self.data[start..start + data.len()].copy_from_slice(data);
            Ok(())
        } else {
            Err(crate::EmulatorError::InvalidMemoryAccess(start_address))
        }
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_ram_read_write() {
        let mut ram = Ram::new(0x1000);
        
        // 测试写入和读取
        ram.write(0x100, 0xAB).unwrap();
        assert_eq!(ram.read(0x100).unwrap(), 0xAB);
        
        // 测试边界条件
        assert!(ram.write(0x10000, 0x12).is_err());
        assert!(ram.read(0x10000).is_err());
    }

    #[test]
    fn test_ram_load() {
        let mut ram = Ram::new(0x1000);
        let data = [0x01, 0x02, 0x03, 0x04];
        
        ram.load(0x200, &data).unwrap();
        
        for i in 0..data.len() {
            assert_eq!(ram.read(0x200 + i as Address).unwrap(), data[i]);
        }
    }
}